
import { ClassName, CtrlType, Events } from "@/Constants";
import { IPixelPos, IRelativePos } from "@/Interface";
import { Utils } from "../../utils";
import Rect from "../basic-shape/Rect";
import Feature from "../Feature";

// 多个子元素的包围集合, 组内子元素不允许形变
export default class Group extends Rect {

    padding = 0;
    cbDropIn = false;  // 接受
    cbResize = false;  // 是否可以拖拽到group之外, 此时应配合 isFixedSize 为true
    _cbDragout = false;
    get cbDragout() {
        return this._cbDragout;
    }
    set cbDragout(bool) {
        if (!bool && this.cbResize) {
            throw '需要先设置cbResize为false'
        }
        this._cbDragout = bool;
    }
    _t_resize = () => { this.resize() }
    _r_resize = () => { this.resize(true) }

    constructor(...features: Feature[]) {   // 相对坐标
        super(0, 0, 0, 0);
        features.forEach(f => this.addMember(f))
        this.resize(true);
        this.className = ClassName.GROUP;
        this.isStroke = false;
        this.isClosePath = true;
        this.fillStyle = "rgba(250, 242, 180, .3)"
        this.hoverStyle = "rgba(250, 242, 180, .4)"
        this.focusStyle = "rgba(250, 242, 180, .5)"
        this.lineDashArr = [8, 12]
        this.lineWidth = .1;
        this.zIndex = -1;
        this.isDelWithChild = false;
        this.cbTransformChild = true;
        this.isFixedSize = true;
        this.ctrlTypes = [CtrlType.SIZE_CTRL, CtrlType.ANGLE_CTRL, CtrlType.WIDTH_CTRL, CtrlType.HEIGHT_CTRL];
    }

    addMember(feature: Feature) {
        if (!Utils.isBasicFeature(feature) || feature.isFixedPos || feature.group) return; // 非基础元素不添加, 固定坐标不添加, 已经在组内或有父元素不添加
        this.addChild(feature, false);
        feature.group = this;
        this.resize();
        feature.on(Events.TRANSLATE, this._t_resize)
        feature.on(Events.RESIZE, this._r_resize)
        feature.on(Events.ROTATE, this._r_resize)
    }
    removeMember(feature: Feature) {
        this.removeChild(feature);
        feature.group = null;
        this.resize();
        feature.off(Events.TRANSLATE, this._t_resize)
        feature.off(Events.RESIZE, this._r_resize)
        feature.off(Events.ROTATE, this._r_resize)
    }

    resize(force = false) {  // 重新创建后重设大小, 注意不要用setPos, setSize,会有bug
        if(this.children.length < 1) return;  // 没有元素不计算大小
        if (!this.cbResize && !force) return;
        const features = this.getBasicChilds();
        let totalPointArr: IRelativePos[] = [];
        features.forEach(f => totalPointArr.push(...f.pointArr));
        const newCenter = Feature.getCenterPos(totalPointArr);
        const ntotalPointArr = this.getPointArr(totalPointArr, -this.angle, newCenter)  // 将所有点旋转-this.angle
        const pointArr =  Feature.getRectWrapPoints(ntotalPointArr)  // 新的group 包围盒的四个点
        this.pointArr = this.getPointArr(pointArr, this.angle, newCenter)  // 新的包围盒在旋转回去
        this.dispatch(new CustomEvent(Events.RESIZE, { detail: { target: this } }))
    }

    override getSvg(pointArr?: IPixelPos[], lineWidth?: number): string {
        return ""
    }

    override destroy() {
        for (let index = this.children.length - 1; index >= -1; index--) {
            const cf = this.children[index];
            if (cf) this.removeMember(cf)
        }
    }

    // flex-start：子项在起点位置对齐
    // flex - end：子项在结束位子对齐
    // center：子项在中心位置对齐
    // space - between两端顶对齐
    // between是中间的意思，就是多余的空白间距在元素中间分配
    // space - around：
    // around是环绕的意思，意思是每个flex子项两侧都环绕互不干扰的等宽的空白间距，最终视觉上边缘两侧的空白只有中间空白宽度一半。
    // space - evenly：
    // evenly是匀称、平等的意思。也就是视觉上，每个flex子项两侧空白间距完全相等。

}